﻿Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Public Class Partikelklasse
    Shared Rand As New Random
    Const Untergrenze As Single = -1
    Enum Arten
        Flaeche
        Explosion
    End Enum

    Structure sPartikel
        Dim Pos As Vector3
        Dim Farbe As Color
        Dim Speed As Vector3
        ''' <summary>
        ''' Die Lebensdauer in Frames. -1 => unendlich! Aufpassen!
        ''' </summary>
        ''' <remarks></remarks>
        Dim Lebensdauer As Integer
        Sub New(ByVal Pos As Vector3, ByVal Farbe As Color, ByVal Speed As Vector3, ByVal Lebensdauer As Integer)
            Me.Pos = Pos
            Me.Farbe = Farbe
            Me.Speed = Speed
            Me.Lebensdauer = Lebensdauer
        End Sub
    End Structure


    Dim Art As Arten
    Dim XMax, ZMax As Single
    Dim HoeheIni As Single
    Dim PartikelMax As Integer
    Dim RMin, RMax, GMin, GMax, BMin, BMax As Integer
    Dim Abdunkeln As Boolean
    Dim Partikel() As sPartikel = {}
    Public Wetter As ObjektSpielfeld.Wetterarten
    Private Sub New()
        Randomize()
    End Sub

    Private Sub setFarbeBereich(ByVal RMin As Integer, ByVal RMax As Integer, ByVal GMin As Integer, ByVal GMax As Integer, ByVal BMin As Integer, ByVal BMax As Integer, ByVal Abdunkeln As Boolean)
        Me.RMin = RMin
        Me.RMax = RMax
        Me.GMin = GMin
        Me.GMax = GMax
        Me.BMin = BMin
        Me.BMax = BMax
        Me.Abdunkeln = Abdunkeln
    End Sub
    Private Sub setPartikelAnz(ByVal PpF As Integer)
        PartikelMax = PpF * XMax * ZMax * HoeheIni
        Array.Resize(Partikel, PartikelMax)
    End Sub

    Sub CreatePartikels(Optional ByVal Oben As Boolean = True)
        For i = 0 To Partikel.Length - 1
            If Partikel(i).Pos.Y < Untergrenze Or Partikel(i).Lebensdauer = 0 Then
                Partikel(i) = New sPartikel(getZufallsPos(Oben), getZufallsFarbe, getZufallsSpeed, -1)
            End If
        Next
    End Sub
    Function getZufallsSpeed() As Vector3

        Return New Vector3(0, -(Rand.NextDouble * 0.5 + 0.2), 0)
    End Function
    Function getZufallsPos(Optional ByVal Oben As Boolean = True) As Vector3
        Dim X As Single = Rand.NextDouble * XMax
        Dim Y As Single
        If Oben Then
            Y = HoeheIni
        Else
            Y = Rand.NextDouble * HoeheIni
        End If
        Dim Z As Single = Rand.NextDouble * -ZMax
        Return New Vector3(X, Y, Z)
    End Function
    Function getZufallsFarbe() As Color
        Dim R As Integer = Rand.Next(RMin, RMax)
        Dim G As Integer = Rand.Next(GMin, GMax)
        Dim B As Integer = Rand.Next(BMin, BMax)
        Return Color.FromArgb(R, G, B)
    End Function


    Public Sub Berechnen()
        For i = 0 To Partikel.Length - 1
            Partikel(i).Pos = Vector3.Add(Partikel(i).Pos, Partikel(i).Speed)
            If Partikel(i).Lebensdauer > 0 Then Partikel(i).Lebensdauer -= 1
        Next

        CreatePartikels() 'evtl. noch neue erschaffen.
    End Sub

    Public Sub Malen()
        If Partikel.Length <= 0 Then Exit Sub
        'Na dann...
        Grafikengine.Grafikkarte.Transform.World = Matrix.Identity
        'Mesh.Malen()

        'Grafikengine.Grafikkarte.SetTexture(0, TexturLandschaft)

        'Berechnen:
        Grafikengine.Grafikkarte.Material = Grafikengine.Mat
        Dim Part As New Stack(Of CustomVertex.PositionColored)
        For i = 0 To Partikel.Length - 1
            If Not Partikel(i).Lebensdauer = 0 Then
                Part.Push(New CustomVertex.PositionColored(Partikel(i).Pos, Partikel(i).Farbe.ToArgb))
                Part.Push(New CustomVertex.PositionColored(Vector3.Add(Partikel(i).Pos, Vector3.Multiply(Partikel(i).Speed, 0.25)), Partikel(i).Farbe.ToArgb))
            End If
        Next

        Dim prim() As CustomVertex.PositionColored = Part.ToArray
        Part.Clear()

        'Anzeigen:
        Grafikengine.Grafikkarte.VertexFormat = CustomVertex.PositionColored.Format
        'Dim M As New Material
        'M.Emissive = Color.White
        'Grafikengine.Grafikkarte.Material = M
        Grafikengine.Grafikkarte.DrawUserPrimitives(PrimitiveType.LineList, prim.Length / 2, prim)
    End Sub

    ''' <summary>
    ''' Erstellt eine Partikelklasse fuers Wetter
    ''' </summary>
    ''' <param name="Spielfeldbreite"></param>
    ''' <param name="Spielfeldhoehe"></param>
    ''' <param name="Wetter"></param>
    ''' <param name="PpF">Partikel pro Feld</param>
    ''' <param name="IniHoehe">Immer vom Meeresspiegel aus (naja etwas hoeher schon, also eher immer von der Ebenenhoehe aus ;))</param>
    ''' <remarks></remarks>
    Public Shared Function CreateWetter(ByVal Spielfeldbreite As Integer, ByVal Spielfeldhoehe As Integer, ByVal Wetter As ObjektSpielfeld.Wetterarten, Optional ByVal PpF As Integer = 3, Optional ByVal IniHoehe As Single = 10) As Partikelklasse
        Dim P As New Partikelklasse
        P.Art = Arten.Flaeche
        P.XMax = Spielfeldbreite
        P.ZMax = Spielfeldhoehe
        P.HoeheIni = 20
        'Farbe festlegen
        P.Wetter = Wetter
        Select Case Wetter
            Case ObjektSpielfeld.Wetterarten.Regen
                P.setFarbeBereich(0, 0, 0, 50, 170, 255, False)
            Case ObjektSpielfeld.Wetterarten.Schnee
                P.setFarbeBereich(230, 255, 230, 255, 230, 255, False)
            Case ObjektSpielfeld.Wetterarten.Sandsturm
                P.setFarbeBereich(230, 255, 230, 255, 70, 170, False)
            Case Else
                'Sonne? welche Partikel bitteschoen!
                P.setPartikelAnz(0)
                Return P 'gleich abbrechen und nicht noch die PartikelAnz festlegen!
        End Select
        'Menge Festlegen
        P.setPartikelAnz(PpF)

        P.CreatePartikels(False)
        Return P
    End Function
End Class
